package cn.ztuo.bitrade.service;

import cn.ztuo.bitrade.constant.TransactionType;
import cn.ztuo.bitrade.dao.BorrowMoneyDao;
import cn.ztuo.bitrade.dao.MemberDao;
import cn.ztuo.bitrade.dao.MemberTransactionDao;
import cn.ztuo.bitrade.dao.MemberWalletDao;
import cn.ztuo.bitrade.entity.*;
import cn.ztuo.bitrade.service.Base.BaseService;
import cn.ztuo.bitrade.util.BigDecimalUtils;
import cn.ztuo.bitrade.util.PredicateUtils;
import cn.ztuo.bitrade.vo.BorrowMoneyVO;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;

/**
 * @author: Xiazt
 * @date: 2020-04-24 17:40
 */
@Service
public class BorrowMoneyService extends BaseService {

    @Autowired
    private BorrowMoneyDao borrowMoneyDao;

    @Autowired
    private MemberDao memberDao;

    @Autowired
    private MemberWalletDao memberWalletDao;

    @Autowired
    private MemberTransactionDao memberTransactionDao;

    @Autowired
    private CoinService coinService;

    @Transactional
    public BorrowMoney saveOrUpdate(Long memberId, BorrowMoney borrowMoney, MemberWallet usdtMemberWallet, String pledgeCoinUnit) {
        Member member = memberDao.findOne(memberId);
        borrowMoney.setJoinMember(member);
        borrowMoney.setBorrowCoin("USDT");
        borrowMoney.setJoinPledgeCoin(coinService.findByUnit(pledgeCoinUnit));
        BorrowMoney result = borrowMoneyDao.save(borrowMoney);
        // 扣除抵押币种余额
        if (borrowMoney.getPledgeMoney().compareTo(BigDecimal.ZERO) <= 0) throw new RuntimeException("数据异常！");
        MemberWallet memberWallet = memberWalletDao.findByCoinAndMemberId(borrowMoney.getJoinPledgeCoin(), memberId);
        memberWallet.setBalance(BigDecimalUtils.sub(memberWallet.getBalance(), borrowMoney.getPledgeMoney()));
        memberWalletDao.save(memberWallet);
        // 抵押币种资产流水
        MemberTransaction pledgeTransaction = new MemberTransaction();
        pledgeTransaction.setMemberId(memberId);
        pledgeTransaction.setSymbol(borrowMoney.getJoinPledgeCoin().getUnit());
        pledgeTransaction.setCreateTime(new Date());
        pledgeTransaction.setAmount(borrowMoney.getPledgeMoney().negate());
        pledgeTransaction.setType(TransactionType.ACCESS_PLEDGE);
        memberTransactionDao.save(pledgeTransaction);

        // 扣除手续费
        if (borrowMoney.getServiceCharge().compareTo(BigDecimal.ZERO) <= 0) throw new RuntimeException("数据异常！");
        usdtMemberWallet.setBalance(BigDecimalUtils.sub(usdtMemberWallet.getBalance(), borrowMoney.getServiceCharge()));
        memberWalletDao.save(usdtMemberWallet);
        // 手续费资产流水
        MemberTransaction serviceChangeTransaction = new MemberTransaction();
        serviceChangeTransaction.setMemberId(memberId);
        serviceChangeTransaction.setSymbol("USDT");
        serviceChangeTransaction.setCreateTime(new Date());
        serviceChangeTransaction.setAmount(borrowMoney.getServiceCharge().negate());
        serviceChangeTransaction.setType(TransactionType.ACCESS_SERVICE_CHARGE);
        memberTransactionDao.save(serviceChangeTransaction);

        return result;
    }

    public Page<BorrowMoney> getBorrowMoneyList(BorrowMoneyVO borrowMoneyVO) {
        ArrayList<BooleanExpression> booleanExpressions = new ArrayList<>();
        // 查询条件
        if (borrowMoneyVO.getPeriod() != null) {
            booleanExpressions.add(QBorrowMoney.borrowMoney.period.eq(borrowMoneyVO.getPeriod()));
        }
        if (borrowMoneyVO.getMemberId() != null) {
            booleanExpressions.add(QBorrowMoney.borrowMoney.joinMember.id.eq(borrowMoneyVO.getMemberId()));
        } else {
            booleanExpressions.add(QBorrowMoney.borrowMoney.status.ne(3));
        }
        if (borrowMoneyVO.getUsername() != null) {
            booleanExpressions.add(QBorrowMoney.borrowMoney.joinMember.username.eq(borrowMoneyVO.getUsername()));
        }
        if (borrowMoneyVO.getPhoneNumber() != null) {
            booleanExpressions.add(QBorrowMoney.borrowMoney.joinMember.mobilePhone.eq(borrowMoneyVO.getPhoneNumber()));
        }
        Predicate predicate = PredicateUtils.getPredicate(booleanExpressions);
        // 排序条件
        Sort sort;
        if ("DESC".equals(borrowMoneyVO.getSort())) {
            sort = new Sort(Sort.Direction.DESC, borrowMoneyVO.getSortField());
        } else {
            sort = new Sort(Sort.Direction.ASC, borrowMoneyVO.getSortField());
        }
        Pageable pageable = new PageRequest(borrowMoneyVO.getPageNum() - 1, borrowMoneyVO.getPageSize(), sort);
        Page<BorrowMoney> all = borrowMoneyDao.findAll(predicate, pageable);
        for (BorrowMoney borrowMoney : all) {
            borrowMoney.getMember().setId(borrowMoney.getJoinMember().getId());
            borrowMoney.getMember().setUsername(borrowMoney.getJoinMember().getUsername());

            borrowMoney.getPledgeCoin().setName(borrowMoney.getJoinPledgeCoin().getName());
            borrowMoney.getPledgeCoin().setUnit(borrowMoney.getJoinPledgeCoin().getUnit());
        }

        return all;
    }

    public BorrowMoney findById(Long id) {
        return borrowMoneyDao.findById(id);
    }

    @Transactional
    public BorrowMoney cancellations(Long memberId, BorrowMoney borrowMoney) {
        // 退回质押金
        if (borrowMoney.getPledgeMoney().compareTo(BigDecimal.ZERO) <= 0) throw new RuntimeException("数据异常！");
        Coin pledgeCoin = borrowMoney.getJoinPledgeCoin();
        MemberWallet pledgeMemberWallet = memberWalletDao.findByCoinAndMemberId(pledgeCoin, memberId);
        pledgeMemberWallet.setBalance(BigDecimalUtils.add(pledgeMemberWallet.getBalance(), borrowMoney.getPledgeMoney()));
        memberWalletDao.save(pledgeMemberWallet);
        // 质押金退回资产流水
        MemberTransaction pledgeTransaction = new MemberTransaction();
        pledgeTransaction.setMemberId(memberId);
        pledgeTransaction.setSymbol(borrowMoney.getJoinPledgeCoin().getUnit());
        pledgeTransaction.setCreateTime(new Date());
        pledgeTransaction.setAmount(borrowMoney.getPledgeMoney());
        pledgeTransaction.setType(TransactionType.CANCELLATIONS_PLEDGE);
        memberTransactionDao.save(pledgeTransaction);

        // 退回手续费
        if (borrowMoney.getServiceCharge().compareTo(BigDecimal.ZERO) <= 0) throw new RuntimeException("数据异常！");
        Coin serviceChargeCoin = coinService.findByUnit("USDT");
        MemberWallet serviceChargeMemberWallet = memberWalletDao.findByCoinAndMemberId(serviceChargeCoin, memberId);
        serviceChargeMemberWallet.setBalance(BigDecimalUtils.add(serviceChargeMemberWallet.getBalance(), borrowMoney.getServiceCharge()));
        memberWalletDao.save(serviceChargeMemberWallet);
        // 手续费退回资产流水
        MemberTransaction serviceChangeTransaction = new MemberTransaction();
        serviceChangeTransaction.setMemberId(memberId);
        serviceChangeTransaction.setSymbol("USDT");
        serviceChangeTransaction.setCreateTime(new Date());
        serviceChangeTransaction.setAmount(borrowMoney.getServiceCharge());
        serviceChangeTransaction.setType(TransactionType.CANCELLATIONS_SERVICE_CHARGE);
        memberTransactionDao.save(serviceChangeTransaction);
        // 修改状态为已撤单
        borrowMoney.setStatus(3);
        return borrowMoneyDao.save(borrowMoney);
    }

}
